<template>
  <teleport :disabled="!toBody" to="body">
    <div class="vb-spinner" v-if="visible" :class="{ 'vb-spinner-light': theme === 'light' }">
      <div class="text-center">
        <div
          :style="size === 'large' ? 'width: 3rem; height: 3rem;' : ''"
          :class="[
            theme ? 'text-' + theme : '',
            'spinner-' + (grow ? 'grow' : 'border'),
            size === 'small' ? `spinner-${grow ? 'grow' : 'border'}-sm` : '',
          ]"
        >
        </div>
        <div v-if="tip" :class="[theme ? 'text-' + theme : '', { 'fs-5': size === 'large' }]" v-html="tip"></div>
      </div>
    </div>
  </teleport>
</template>
<script lang='ts'>
import { defineComponent, ref, watch } from "vue";

export default defineComponent({
  name: "VbSpinner",
  props: {
    theme: {
      default: "",
      validator(v: string) {
        return ["", "primary", "secondary", "success", "danger", "warning", "info", "light", "dark"].indexOf(v) !== -1;
      },
    },
    toBody: { type: Boolean, default: false },
    modelValue: { type: Boolean, default: false },
    grow: { type: Boolean, default: false },
    size: {
      default: "middle",
      validator(v: string) {
        return ["small", "middle", "large"].indexOf(v) !== -1;
      },
    },
    tip: { type: String, default: "" },
  },
  emits: ["start", "end"],
  setup(props: any) {
    const visible = ref(false);
    watch(
      () => props.modelValue,
      (val) => {
        visible.value = val;
      }
    );
    return {
      visible,
    };
  },
});
</script>
<style>
.vb-spinner {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
  background-color: rgba(255, 255, 255, 0.7);
}
.vb-spinner-light {
  background-color: rgba(0, 0, 0, 0.15);
}
.vb-spinner > div {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
}
</style>
